
import com.ridgesoft.robotics.AnalogInput;
import com.ridgesoft.robotics.DirectionListener;
import com.ridgesoft.robotics.ShaftEncoder;

public class AnalogShaftEncoder extends Thread implements ShaftEncoder, DirectionListener {

    private AnalogInput mInput;
    private int mLowThreshold;
    private int mHighThreshold;
    private boolean mIsForward;
    private int mCounts;
    private int mPeriod;
    private boolean isEnabled = true;

    public AnalogShaftEncoder(AnalogInput input, int lowThreshold, int highThreshold, int period, int threadPriority) {
        mInput = input;
        mLowThreshold = lowThreshold;
        mHighThreshold = highThreshold;
        mPeriod = period;
        mIsForward = true;
        mCounts = 0;
        setPriority(threadPriority);
        setDaemon(true);
        start();
    }

    public int getRate() {
        return 0; // rate calculation not supported
    }

    public int getCounts() {
        return mCounts;
    }

    public void resetCounts() {
        mCounts = 0;
    }

    public void setEnabled(boolean enabled) {
        this.isEnabled = enabled;
    }

    public void run() {
        try {
            // take initial sensor sample
            boolean wasHigh = false;
            if (mInput.sample() > mLowThreshold) {
                wasHigh = true;
            }
            while (true) {
                // sample the sensor and count
                // spoke edges
                int value = mInput.sample();
                if (wasHigh) {
                    if (value < mLowThreshold) {
                        if (isEnabled) {
                            if (mIsForward) {
                                mCounts++;
                            } else {
                                mCounts--;
                            }
                        }
                        wasHigh = false;
                    }
                } else {
                    if (value > mHighThreshold) {
                        if (isEnabled) {
                            if (mIsForward) {
                                mCounts++;
                            } else {
                                mCounts--;
                            }
                        }
                        wasHigh = true;
                    }
                }
                Thread.sleep(mPeriod);
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    public void updateDirection(boolean mForward) {
        mIsForward = mForward;
    }
}